/*
 * CSV2XML.java
 *
 * Created on 8. listopad 2006, 15:11
 *
 */

package cz.results.winter6.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CSV2XML {
    
    
    public CSV2XML() {
    }
    
    public static void convertCSVFile2XMLFile(String csvFilename, String xmlFilename, String xmlVzorFilename, String oddelovac){
        String line;
        String line1;
        
        try {
            
            BufferedReader csvIn = new BufferedReader(new FileReader(csvFilename));
            BufferedReader xmlVzor;
            BufferedWriter xmlOut = new BufferedWriter(new FileWriter(xmlFilename));
            
            xmlOut.write("<?xml version=\"1.0\" encoding=\"iso-8859-2\"?>"+"\n\n");
            xmlOut.write("<root>\n");
            
            while((line = csvIn.readLine()) != null) {               //pres vsechny radky v csv souboru
                
                String[] col = line.split(oddelovac);
                
                xmlVzor = new BufferedReader(new FileReader(xmlVzorFilename));  //musim znovu otevrit soubor s xml vzorem
                
                while((line1 = xmlVzor.readLine()) != null) {
                    xmlOut.write(doplnXML(line1,col)+"\n");
                }
                xmlVzor.close();
            }
            
            xmlOut.write("</root>\n");
            
            csvIn.close();
            xmlOut.close();
            
        } catch (IOException e) {
            System.out.println("!CSV2XML: i/o chyba:...v convertCSVFile2XMLFile");
        }
    }
    
    
    /** nahradi vsechny vyskyty */
    public static String doplnXML(String xmlVzor, String[] col){
        String patternStr;
        
        while( !(patternStr=najdiStr("(\\(\\$.*?\\))",xmlVzor)).equals("")){
            
            int cisloSloupce = getCisloSloupce(patternStr);
            String prikaz = getPrikaz(patternStr);
            int  parametr = getParametr(patternStr);
            String pom=zformatuj(cisloSloupce,prikaz,parametr,col);
            
            if(parametr!=0){
                xmlVzor=nahradStr(xmlVzor,"\\(\\$"+cisloSloupce+":"+prikaz+":"+parametr+"\\)",pom);
            } else {
                xmlVzor=nahradStr(xmlVzor,"\\(\\$"+cisloSloupce+":"+prikaz+":\\)",pom);
            }
        }
        return xmlVzor;
    }
    
    public static String zformatuj(int cisloSloupce, String prikaz, int parametr, String[] col){
        String out="";
        int cisloPrikazu=0;
        
        if(cisloSloupce<=col.length){
            if(prikaz.equals("f2l")){                       //prevede float na long
                cisloPrikazu=1;
            }
            
            switch(cisloPrikazu){
                case 1:
                    if(!upravStr(col[cisloSloupce-1]).equals("")){
                        String pom1=najdiStr(",(.*)",upravStr(col[cisloSloupce-1]));
                        if(pom1.equals("")){
                            out=upravStr(col[cisloSloupce-1])+"000";
                        } else {
                            for (int i = pom1.length(); i < 3; i++) {
                                pom1=pom1+"0";
                            }
                            out = nahradStr(upravStr(col[cisloSloupce-1]),",.*",pom1);
                        }
                    }
                    break;
                default: out = upravStr(col[cisloSloupce-1]);
            }
        }
        return out;
    }
    
    public static int getCisloSloupce(String patternStr){
        return Integer.valueOf(najdiStr("\\(\\$(.*?):.*?:.*?\\)",patternStr).trim());
    }
    
    public static String getPrikaz(String patternStr){
        return najdiStr("\\(\\$.*?:(.*?):.*?\\)",patternStr).trim();
    }
    
    public static int getParametr(String patternStr){
        String pom = najdiStr("\\(\\$.*?:.*?:(.*?)\\)",patternStr).trim();
        if(!pom.equals("")){
            return Integer.valueOf(najdiStr("\\(\\$.*?:.*?:(.*?)\\)",patternStr).trim());
        } else {
            return 0;
        }
    }
    
    /**
     *  najde ve vstupnim retezci pattern a ten nahradi replacementStr
     *
     *  @param inputStr v cem se vyhledava
     *  @param patternStr co se vyhledava, regularni vyraz splnujici parametry regularniho vyrazu
     *  @param replacementStr cim se nahrazuje
     */
    public static String nahradStr(String inputStr, String patternStr, String replacementStr){
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(inputStr);
        
        return matcher.replaceAll(replacementStr);
    }
    
    /** vraci true jestlize pattern je obsazen ve vstupnim retezci 
     !!!!!!!!! vstupni retezec musi odpovidat zcela !!!!*/
    public static boolean isIn(String inputStr, String patternStr){
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(inputStr);
        
        return matcher.matches();
    }
    
    /** najde prvni retezec ktery odpovida patternu a vrati retezec, ktery je v paternu umisten v kulatych
     *  zavorkach
     *  @param patternStr regularni vyraz, ktery obsahuje kulate zavorky
     *  @return retezec, ktery vyhovuje patternu a je v kulatych zavorkach v patternu
     */
    public static String najdiStr(String patternStr, String line){
        Pattern pattern;
        String groupStr="";
        Matcher matcher;
        
        pattern=Pattern.compile(patternStr);
        matcher=pattern.matcher(line);
        if(matcher.find()){
            groupStr=matcher.group(1);
        }
        return groupStr.trim();
    }
    
    /** odstrani uvozovky, zmensi pocet mezer na jednu a otrimuje  */
    public static String upravStr(String inStr){
        return zmensiPocetMezer(nahradStr(inStr,"\""," ")).trim();
    }
    
    /** vetsi pocet mezer za sebou nahradi jednou mezerou
     *  @param inStr vstupni retezec, ve kterem budou nahrazeny mezery
     *  @return retezec s nahrazenymi mezerami
     */
    public static String zmensiPocetMezer(String inStr){
        return nahradStr(inStr," +"," ");
    }
    
    /** precte xml vzor ze souboru na disku soubor musi obsahovat na libovolnem miste xml="......"
     *  vlastni vzor je uzavren v uvozovkach napr.: xml="blablablablablabl"
     *
     *  @param xmlVzorFilename jmeno souboru, ze ktereho je cten vzor
     *  @return vrati vlastni vzor, tedy to co je mezi uvozovkama
     */
    public static String prectiXMLVzor(String xmlVzorFilename){
        String line;
        String celySoubor="";
        String out="";
        
        try {
            
            BufferedReader in = new BufferedReader(new FileReader(xmlVzorFilename));
            
            /* cely soubor se nacte do jednoho retezce */
            while((line = in.readLine()) != null) {
                celySoubor=celySoubor+line+"\n";
            }
            
            out=najdiStr("xml=\"(.*)\"",celySoubor);
            in.close();
            
        } catch (IOException e) {
            System.out.println("!CSV2XML: i/o chyba:...v cteni XML vzoru");
        }
        return out;
    }
    
        
    public static void main(String[] args){
        //String xmlVzor="<poradi>($1)</poradi><rgc>($2)</rgc><jmeno>($3)</jmeno><narozen>($4)</narozen><VK>($5)</VK><VT>($6)</VT><oddil>($7)</oddil><cas>($8)</cas><body>($9)</body><vysledek>($10)</vysledek><cas>($11)</cas><body>($12)</body><vysledek>($13)</vysledek><celkem>($14)</celkem><zebricek>($15)</zebricek>";
        //String xmlVzor=prectiXMLVzor("/home/winter6/xmlvzor.txt");
        convertCSVFile2XMLFile("/home/winter6/data.csv","/home/winter6/data.xml","/home/winter6/xmlvzor.txt",";");
        
    }
    
}
